import {objectIsEq} from "@/utils/biz/common/BizUtils";
import {Observer} from "@/utils/observer/Observer";
import {UserCommitApi} from "@/api/user_common";
import {ApiShangHaiShiYiXianUtil} from "@/utils/biz/information/customapi/ApiShangHaiShiYiXianUtil";

/**
 * 使用场景--非信息发布类的模板，可以去适配类似接口形式的数据
 */
class ApiDataUtil extends Observer{
  constructor(self, deviceInfo = {}, item) {
    super();
    // 外部组件
    this.catcheInfo = self;
    // 设备信息
    this.deviceInfo = deviceInfo;
    // 当前组件信息
    this.currentInfo = item || {};
    // 空数据定时器
    this.emptyDataInterval = null;
    this.params = {};
    // 排班墙索引
    this.currentDataIndex = -1;
    this.apiDataIndex = -1;
    // 当前组件信息
    this.currentInfo = item || {};
    // 接口配置
    this.apiData = {
      method: "GET",
      fullDataList: [],
      // 分组数据
      groupData: [],
      // 请求地址
      reqUrl: "",
      ApiSign: "",
      // 接口请求频次
      refreshNum: 10,
      // 行数
      scrollNumber: 10,
      // 策略KY
      reqKey: "",
      // 是否切屏
      switchState: false,
      // 切屏间隔
      switchTime: 10,
      // 是否配置接口
      apiState: false,
      // 接口类型
      apiType: "1",
      // 数据结构
      dataType: "array",
      // 当前屏
      currentIndex: -1,
      // 设置数据
      setData: false,
      // 接口扩展参数
      apiParams: {},
      // 后台无感刷新
      backstageRefresh: false,
      // 是否执行消息刷新
      isRefreshByMsg: true,
    };
  }
  /**
   * 消息监听入口
   * @param bizType
   * @param msgContent
   */
  update(bizType,msgContent) {
    // 在这里显示监听的消息
    if (this[bizType]){
      this[bizType](msgContent);
    }
  }
  /**
   * 初始化
   */
  async init() {
    if (this.currentInfo.options.config && this.currentInfo.options) {
      // 获取当前组件的配置信息
      let configObj = this.currentInfo.options[this.currentInfo.options.config];
      // 接口标识
      this.apiData.reqKey = configObj.ApiType || "";
      // 接口类型
      this.apiData.apiType = configObj.apiType || "1";
      // 接口地址
      this.apiData.reqUrl = configObj.ApiAddress || configObj['Api'] || "";
      // 接口标识
      this.apiData.ApiSign = configObj.ApiSign || "";
      // 接口请求频次
      this.apiData.refreshNum = configObj.frequencyApi || 0;
      // 行数
      this.apiData.scrollNumber = configObj.patientListTotal || 10;
      // 是否开启切屏
      this.apiData.switchState = configObj.switchState || false;
      // 切屏时间
      this.apiData.switchTime = configObj.switchTime || 10;
      // 数组 或 对象
      this.apiData.dataType = configObj.dataType || "array";
      // 是否配置接口
      this.apiData.apiState = configObj.dataType || false;

      // 是否主动设置数据
      this.apiData.setData = (false === configObj.setData) ? configObj.setData : true;
      // 是否主屏 表示会执行分组逻辑，然后发送切屏请求
      this.apiData.isMainScreen = configObj.isMainScreen || false;
      // 主屏 code
      this.apiData.isMainScreenCode = configObj.isMainScreenCode || false;
      // 接口参数
      this.apiData.apiParams = configObj.apiParams || {};
      // 是否无感刷新
      this.apiData.backstageRefresh = true === configObj.backstageRefresh || false;
      // 是否执行消息刷新
      // this.apiData.isRefreshByMsg = true === configObj.isRefreshByMsg || false;

      this.apiData.method = configObj.rqMethod || 'GET'
      // 获取初始化数据
      await this.getDataSource("1");
      // 定时刷新
      this.comSetInterval();
    }
  }

  /**
   * 重新加载数据
   * @param data
   */
  async reloadData(data) {
    if (this.apiData.isRefreshByMsg === true) {
      await this.getDataSource("2", data);
    }
  }
  /**
   * 加载数据
   * @param type 1 全量刷新
   * @param data 2 局部更新
   */
  async getDataSource(type = "1", data) {
    let self = this;
    try {
      // 配置接口标识 特质逻辑
      if (2 === this.apiData.reqKey) {
        // 标识不为空
        if (this.apiData.ApiSign !== "") {
          let apiType = this.apiData.ApiSign;
          let resultData
          switch (apiType) {
            case "custom_shanghaishiyi_prescription_list":
              // 上海市一 -- 获取药房数据
              resultData = await ApiShangHaiShiYiXianUtil.getPrescriptionList(self, this.apiData);
              await this.resetData(resultData,this.apiData.backstageRefresh)
              break;
            case "custom_shanghai_syncSurgeryData":
              // 上海市一 -- 获取排班
              resultData = await ApiShangHaiShiYiXianUtil.getScheduleList(self, this.apiData);
              await this.resetData(resultData,this.apiData.backstageRefresh)
              break;
          }
        }
      } else {
        if (this.apiData.reqUrl !== "") {
          // 获取接口数据
          let apiParams = this.apiData.apiParams;
          let formJson = {};
          if (objectIsEq(apiParams, "Object")) {
            formJson = {...apiParams};
          }
          // TODO 是否内置设备参数,是的话直接拼接上，这里可以从模板中进行维护
          if(true){
            formJson['terminalId'] = this.deviceInfo.screenId;
            formJson['terminalType'] = this.deviceInfo.screenType;
          }
          const {code, data} = await UserCommitApi.getChangeDataSource(this.apiData,formJson);
          if (200 === code) {
            this.resetData(data, this.apiData.backstageRefresh);
          }
        }
      }

    } catch (e) {
      self.handleWriteLog("sdkServices", "getDataSource --> 获取接口失败" + JSON.stringify(e.stack));
    }
  }

  /**
   * 重置数据
   * @param data
   * @param backstageRefresh
   */
  resetData(data, backstageRefresh) {
    if (this.apiData.switchState === false) {
      this.setData(data);
      return;
    }
    if (true === backstageRefresh) {
      this.setDataGroupOnly(data);
    } else {
      this.setSetIntervalGroup(data);
    }
    this.openEmptyData(data);
  }

  setData(data) {
    try {
      const formRef = this.catcheInfo.$refs["vFormRef"];
      if (formRef) {
        formRef.executeChildMethod(this.currentInfo?.id, "refreshData", data);
      }
    } catch (e) {
      this.catcheInfo.handleException("sdkBizServices", "候诊屏通用配置 -- 设置数据错误 -- >", JSON.stringify(e.stack));
    }
  }

  /**
   * 设置分组数据
   * @param data
   */
  setDataGroupOnly(data) {
    this.apiData.groupData = this.groupBy(data, this.apiData.scrollNumber);
    // 刷新当前视图
    let index = this.apiDataIndex;
    if (index >= 0 && this.apiData.groupData.length - 1 >= index) {
      this.setData(this.apiData.groupData[index]);
    } else {
      if (this.apiData.groupData.length > 0) {
        this.setData(this.apiData.groupData[this.apiData.groupData.length - 1]);
      }
    }
  }

  /**
   * 定时器分组
   * @param data
   */
  setSetIntervalGroup(data = []) {
    if (this.apiData.switchState === false) {
      return;
    }
    if (this.groupSetInterval != null) {
      clearInterval(this.groupSetInterval);
    }
    // 设置分组数据
    if (this.apiData.scrollNumber > data.length) {
      this.setData(data);
      return;
    }
    this.apiData.groupData = this.groupBy(data, this.apiData.scrollNumber);
    let self = this;
    if (this.apiData.groupData.length > 0) {
      try {
        console.info("切屏定时任务定时器正在执行：————————————");
        let index = 0;
        if (this.currentDataIndex !== -1) {
          index = this.currentDataIndex;
        }
        if (index > this.apiData.groupData.length - 1) {
          index = 0;
        }
        // 请求接口
        this.setData(this.apiData.groupData[index] || []);
        // 是否主动设置数据，当开启了切屏才行
        if (true === this.apiData.setData) {
          index++;
          this.groupSetInterval = setInterval(async function () {
            // 重置当前切屏索引
            self.apiDataIndex = index;
            // 强制刷新
            if (self.beginIndex === 0) {
              index = 0;
              self.beginIndex = -1;
            }
            console.info("切屏次数：————————————" + index);
            let isLast = false;
            // 如果是最后一屏 刷新数据
            if (self.apiData.backstageRefresh === true) {
              // 最后一次切屏刷新全量数据，重新分组
              if (self.apiData.groupData.length === 1 || index === self.apiData.groupData.length - 1) {
                // 无感刷新
                isLast = true;
              }
            }
            if (self.apiData.groupData.length === 1) {
              index = 0;
              // 重置当前切屏索引
              self.apiDataIndex = index;
            }
            if (self.apiData.groupData.length - 1 >= index) {
              self.setData(self.apiData.groupData[index] || []);
              index++;
              // 重置当前切屏索引
              self.apiDataIndex = index;
            } else {
              index = 0;
              // 重置当前切屏索引
              self.apiDataIndex = index;
              self.setData(self.apiData.groupData[index] || []);
            }
            if (isLast) {
              await self.getDataSource(self.apiData.backstageRefresh);
            }
            // 请求接口
          }, self.apiData.switchTime * 1000);
        }
      } catch (e) {
        this.catcheInfo.handleException("sdkServices", "groupSetInterval --> groupSetInterval 写入数据异常", JSON.stringify(e.stack));
      }
    } else {
      this.setData([]);
    }
  }

  /**
   * 空数据情况下 执行自定刷新逻辑
   */
  openEmptyData(data) {
    if (false === this.apiData.backstageRefresh) {
      return;
    }
    let self = this;
    if (this.emptyDataInterval != null) {
      clearInterval(this.emptyDataInterval);
    }
    this.emptyDataInterval = null;

    if (objectIsEq(data, "Array")) {
      if (this.apiData.groupData < 2) {
        this.emptyDataInterval = setInterval(async function () {
          await self.getDataSource("1");
          // 请求接口
        }, self.apiData.refreshNum * 1000);
      }
    }
  }

  /**
   * 定时刷新接口
   */
  comSetInterval() {
    // 通过消息刷新，便不执行定时任务
    if (this.apiData.isRefreshByMsg === false) {
      return;
    }
    // 开启了
    if (this.apiData.backstageRefresh === true) {
      return;
    }
    // 设置分组数据
    if (this.apiData.refreshNum > 0) {
      let self = this;
      try {
        console.info("接口请求定时器正在执行：————————————");
        setInterval(async function () {
          await self.getDataSource();
          // 请求接口
        }, self.apiData.refreshNum * 1000);
      } catch (e) {
        this.catcheInfo.handleException("sdkServices", "comSetInterval --> getDataSource执行异常", JSON.stringify(e.stack));
      }
    }
  }

  //分组
  groupBy(arr, groupSize) {
    let chunks = [];
    for (let i = 0; i < arr.length; i += groupSize) {
      chunks.push(arr.slice(i, i + groupSize));
    }
    return chunks;
  }

  /**
   * 转Map
   * @param arr
   * @param key
   * @returns {*}
   */
  arrayToMap(arr,key){
    return arr.reduce((total,currentValue)=>{
      total[currentValue[key]]=currentValue;
      return total;
    },{});
  }
}

export {ApiDataUtil};
